﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static Lhxzn.LangExtractor.IniFile;


#region 文件信息
/****************************************************************
*	公司名称：福建力和行智能科技有限公司
*   作    者：Jeff
*   CLR 版本：4.0.30319.42000
*   创建时间：12/31/2024 5:35:15 PM
*	用 户 名：zheqichen 
*   描述说明：
*
*   修改历史：
*		1）	修 改 人：
*			修改日期：
*			修改内容：			
*
*****************************************************************/
#endregion

namespace Lhxzn.LangExtractor
{
    /// <summary>
    /// 类    名:AnnotationManager
    /// 描    述:用于管理未翻译标注
    /// 修改时间:12/31/2024 5:35:15 PM
    /// </summary>
    public class AnnotationManager
    {
        #region 成员变量

        #region private



        #endregion


        #region protected



        #endregion


        #region public
        /// <summary>
        /// 匹配的未翻译标注
        /// </summary>
        public class MatchAnnotation
        {
            public int Index { get;set; }
            public string LngFileName { get; set; }

            public string MatchText { get; set; }

            public int LineIndex { get; set; }
        }

        /// <summary>
        /// 语言档管理器
        /// </summary>
        public LngFileManager LngFileManager { get; set; }

        public Dictionary<string, List<string>> m_dict = new Dictionary<string, List<string>>();

        public MatchAnnotation LastSelectedAnnotation { get; set; }
        #endregion

        #endregion


        #region 构造函数
        /// <summary>
        /// 函 数 名:构造函数
        /// 函数描述:默认构造函数
        /// 修改时间:12/31/2024 5:35:15 PM
        /// </summary>
        public AnnotationManager(LngFileManager lngFileManager)
        {
            LngFileManager = lngFileManager;
        }

        #endregion

        #region 父类函数重载、接口实现

        #endregion

        #region 函数

        #region private



        #endregion


        #region protected



        #endregion


        #region public
        /// <summary>
        /// 找上个语言标注
        /// </summary>
        /// <returns></returns>
        public MatchAnnotation FindLastAnnotation()
        {
            List<MatchAnnotation> showingAnnotations = GetShowingAnnotations();
            if (LastSelectedAnnotation == null && showingAnnotations.Count > 0)
            {
                LastSelectedAnnotation = showingAnnotations.FirstOrDefault();
                return LastSelectedAnnotation;
            }
            var next = showingAnnotations.OrderBy(item => item.LineIndex).
                LastOrDefault(item => item.LineIndex < LastSelectedAnnotation.LineIndex&& LastSelectedAnnotation.LngFileName==item.LngFileName);
            if (next == null)
            {
                var lngFile = LngFileManager.CurrentPackage.LanguageFiles.FirstOrDefault(item => Path.GetFileName(item.FilePath) == LngFileManager.SelectedLngFileName);
                var files = LngFileManager.CurrentPackage.LanguageFiles;
                int startIndex = files.IndexOf(lngFile);
                if (startIndex < 0 || startIndex > files.Count)
                {
                    startIndex = 0;
                }
                for (int i = startIndex-1; i >=0; i--)
                {
                    List<MatchAnnotation> annotations = GetMatchedAnnotations(Path.GetFileName(files[i].FilePath));
                    if (annotations.Count == 0)
                    {
                        continue;
                    }
                    LastSelectedAnnotation = annotations.OrderBy(item => item.LineIndex).LastOrDefault();
                    return LastSelectedAnnotation;
                }
                return null;
            }
            LastSelectedAnnotation = next;
            return next;
        }

        /// <summary>
        /// 找下个未翻译标注
        /// </summary>
        /// <returns></returns>

        public MatchAnnotation FindNextAnnotation()
        {
            List< MatchAnnotation > showingAnnotations= GetShowingAnnotations();
            if (LastSelectedAnnotation == null&& showingAnnotations.Count>0)
            {
                LastSelectedAnnotation = showingAnnotations.FirstOrDefault();
                return LastSelectedAnnotation;
            }
            var next = showingAnnotations.OrderBy(item => item.LineIndex).
                FirstOrDefault(item => item.LineIndex > LastSelectedAnnotation.LineIndex && LastSelectedAnnotation.LngFileName == item.LngFileName);
            if (next == null)
            {
                var lngFile = LngFileManager.CurrentPackage.LanguageFiles.FirstOrDefault(item => Path.GetFileName(item.FilePath) == LngFileManager.SelectedLngFileName);
                var files = LngFileManager.CurrentPackage.LanguageFiles;
                int startIndex = files.IndexOf(lngFile);
                if (startIndex<0|| startIndex> files.Count)
                {
                    startIndex = 0;
                }
                for (int i = startIndex+1; i < files.Count; i++)
                {
                    List<MatchAnnotation> annotations = GetMatchedAnnotations(Path.GetFileName(files[i].FilePath));
                    if (annotations.Count == 0)
                    {
                        continue;
                    }
                    LastSelectedAnnotation = annotations.OrderBy(item=>item.LineIndex).FirstOrDefault();
                    return LastSelectedAnnotation;
                }
                return null;
            }
            LastSelectedAnnotation = next;
            return next;
        }

        /// <summary>
        /// 获取当前选择语言文件的未翻译标注
        /// </summary>
        /// <returns></returns>
        public List<MatchAnnotation> GetShowingAnnotations()
        {
            return GetMatchedAnnotations(LngFileManager.SelectedLngFileName,LngFileManager.SelectedSectionName);
        }

        /// <summary>
        /// 获取指定语言文件的未翻译标注
        /// </summary>
        /// <param name="lngFileName"></param>
        /// <param name="sectionName"></param>
        /// <returns></returns>
        public List<MatchAnnotation> GetMatchedAnnotations(string lngFileName, string sectionName = "")
        {
            List<MatchAnnotation> matches = new List<MatchAnnotation>();
            List<string> annotations = GetAnnotations(lngFileName);
            var lngFile = LngFileManager.CurrentPackage.LanguageFiles.FirstOrDefault(item=>Path.GetFileName(item.FilePath)== lngFileName);
            if (lngFile == null) { return matches; }

            string text = Regex.Replace(string.IsNullOrEmpty(sectionName)?lngFile.GetText():lngFile.GetSectionText(sectionName), @"\r?", "");
            if (string.IsNullOrEmpty(text))
            {
                return matches;
            }
            foreach (string annotation in annotations)
            {
                int startIndex = 0;
                while ((startIndex = text.IndexOf(annotation, startIndex)) != -1)
                {
                    matches.Add(new MatchAnnotation()
                    {
                        Index=matches.Count(),
                        LngFileName = lngFileName,
                        MatchText = annotation,
                        LineIndex=startIndex
                    });
                    startIndex += annotation.Length;
                }
            }
            return matches;
        }

        /// <summary>
        /// 获取指定语言文件的未翻译标注匹配字符
        /// </summary>
        /// <param name="lngFileName"></param>
        /// <returns></returns>
        public List<string> GetAnnotations(string lngFileName)
        {
            List<string> annotations = new List<string>();
            if (!m_dict.ContainsKey(lngFileName))
            {
                m_dict.Add(lngFileName, annotations);
            }

            return m_dict[lngFileName];
        }

        /// <summary>
        /// 设置未翻译标注匹配字符
        /// </summary>
        /// <param name="lngFileName"></param>
        /// <param name="annotations"></param>
        public void SetAnnotations(string lngFileName,List<string> annotations)
        {
            m_dict[lngFileName]= annotations;
        }

        /// <summary>
        /// 添加未翻译标注匹配字符
        /// </summary>
        /// <param name="lngFileName"></param>
        /// <param name="annotation"></param>
        public void AddAnnotation(string lngFileName,string annotation)
        {
            var list = GetAnnotations(lngFileName);
            if (!list.Contains(annotation))
            {
                list.Add(annotation);
            }
        }

        /// <summary>
        /// 添加多个未翻译标注匹配字符
        /// </summary>
        /// <param name="lngFileName"></param>
        /// <param name="annotations"></param>
        public void AddAnnotations(string lngFileName,List<string> annotations)
        {
            var list = GetAnnotations(lngFileName);
            foreach (string annotation in annotations)
            {
                if (!list.Contains(annotation))
                {
                    list.Add(annotation);
                }
            }
        }

        /// <summary>
        /// 删除未翻译标注字符
        /// </summary>
        /// <param name="lngFileName"></param>
        /// <param name="sectionName"></param>
        /// <param name="annotation"></param>
        public void DeleteAnnotation(string lngFileName, string sectionName, string annotation)
        {
            var list = GetAnnotations(lngFileName);
            list.Remove(annotation);
        }

        /// <summary>
        /// 删除多个未翻译标注匹配字符
        /// </summary>
        /// <param name="lngFileName"></param>
        /// <param name="sectionName"></param>
        /// <param name="annotations"></param>
        public void DeleteAnnotations(string lngFileName, string sectionName, List<string> annotations)
        {
            var list = GetAnnotations(lngFileName);
            foreach (string annotation in annotations)
            {
                if (list.Contains(annotation))
                {
                    list.Remove(annotation);
                }
            }
        }

        /// <summary>
        /// 初始化未翻译标注匹配字符字典
        /// </summary>
        /// <param name="dict"></param>
        public void InitializeAnnotationDict(Dictionary<string, List<string>> dict)
        {
            m_dict = dict;
        }

        /// <summary>
        /// 通过语言包初始化
        /// </summary>
        /// <param name="package"></param>
        public void InitializeAnnotationDict(LanguagePackage package)
        {
            m_dict = new Dictionary<string, List<string>>();
            foreach (LanguageFile file in package.LanguageFiles)
            {
                var fileName = Path.GetFileName(file.FilePath);
                m_dict.Add(fileName,new List<string>());
                Dictionary<string, Dictionary<string, KeyData>> iniCache = file.GetIniCache();
                foreach (var section in iniCache)
                {
                    foreach (var item in section.Value)
                    {
                        m_dict[fileName].Add(item.Key+"="+item.Value.Value);
                    }
                }
            }
        }

        /// <summary>
        /// 通过语言包添加未翻译匹配字符
        /// </summary>
        /// <param name="package"></param>
        public void AddAnnotationsFromPackage(LanguagePackage package)
        {
            foreach (LanguageFile file in package.LanguageFiles)
            {
                var fileName = Path.GetFileName(file.FilePath);
                if (!m_dict.ContainsKey(fileName))
                {
                    m_dict.Add(fileName, new List<string>());
                }

                Dictionary<string, Dictionary<string, KeyData>> iniCache = file.GetIniCache();
                foreach (var section in iniCache)
                {
                    foreach (var item in section.Value)
                    {
                        if(!m_dict[fileName].Contains(item.Key + "=" + item.Value.Value))
                            m_dict[fileName].Add(item.Key+"="+item.Value.Value);
                    }
                }
            }
        }

        /// <summary>
        /// 清理未翻译匹配字符
        /// </summary>
        public void ClearAllAnnotations()
        {
            m_dict.Clear();
        }

        #endregion

        #endregion
    }
}
